
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>TreeMap与TreeSet的实现原理 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>TreeMap与TreeSet的实现原理 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">文档中描述的红黑树（Red-Black Tree）具有哪五个核心特性？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">1. 每个节点要么是红色，要么是黑色。<br>2. 根节点是黑色。<br>3. 每个叶子节点（NIL 节点）是黑色。<br>4. 红色节点的子节点必须是黑色。<br>5. 从根节点到每个叶子节点的路径上，黑色节点的数量必须相同。</div>
          </div>
          <div class="card-source">来源: 1. 红黑树数据结构的基础 - 红黑树概述</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">TreeMap 和 TreeSet 的查找、插入和删除操作的时间复杂度是多少？为什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">时间复杂度为 O(log n)。因为它们都基于红黑树实现，红黑树是一种自平衡的二叉查找树，其高度是平衡的，从而保证了高效的操作性能。</div>
          </div>
          <div class="card-source">来源: 1. 红黑树数据结构的基础 - 红黑树概述</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">TreeSet 是如何利用 TreeMap 来实现其功能的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">TreeSet 内部包含一个 TreeMap 实例。TreeSet 中存储的元素实际上是作为 TreeMap 的键（key），而对应的值（value）则统一使用一个静态的常量对象 PRESENT 作为占位符。所有操作如添加、删除等都委托给内部的 TreeMap 实现。</div>
          </div>
          <div class="card-source">来源: 3. TreeSet 的实现原理</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">向 TreeMap 中插入一个新键值对（put 操作）主要包含哪几个步骤？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">主要包含三个步骤：<br>1. **查找位置**：根据键（key）的比较结果，从根节点开始查找到合适的插入位置。<br>2. **插入节点**：创建新节点并将其链接到父节点。<br>3. **平衡调整**：调用 `fixAfterInsertion` 方法，通过颜色调整和旋转操作来恢复红黑树的平衡。</div>
          </div>
          <div class="card-source">来源: 2. TreeMap 的实现原理 - TreeMap 插入过程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">TreeSet 源码中的 PRESENT 对象的作用是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">PRESENT 是一个静态常量对象，在 TreeSet 内部的 TreeMap 中充当所有键（key）的统一值（value）。由于 TreeSet 是一个集合，只关心元素的存与否，而其底层 TreeMap 需要存储键值对，因此使用 PRESENT 作为所有值的占位符。</div>
          </div>
          <div class="card-source">来源: 3. TreeSet 的实现原理 - TreeSet 的实现</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在 TreeMap 插入新节点后，`fixAfterInsertion` 方法通过哪两种主要调整来维持红黑树的平衡性？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`fixAfterInsertion` 方法通过两种主要调整来维持平衡：1. **颜色调整**：根据父节点和叔父节点的颜色来改变相关节点的颜色。2. **旋转调整**：在特定情况下，通过左旋（leftRotate）或右旋（rightRotate）来调整树的结构，以满足红黑树的特性。</div>
          </div>
          <div class="card-source">来源: 2. TreeMap 的实现原理 - fixAfterInsertion：插入后平衡树</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">TreeMap 和 TreeSet 之间的主要区别是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">主要区别在于存储内容和用途。TreeMap 用于存储有序的键值对（key-value），而 TreeSet 用于存储不重复的、有序的元素（只存储键）。TreeSet 的内部实现是基于 TreeMap 的一个封装。</div>
          </div>
          <div class="card-source">来源: 5. 总结</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">实现</div>
          <div class="card-question">TreeSet 的 `add(E e)` 方法是如何确保元素不重复的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">实现</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">TreeSet 的 `add` 方法通过调用其内部 TreeMap 的 `put(e, PRESENT)` 方法来实现。TreeMap 的 `put` 方法在键 `e` 不存在时会添加新条目并返回 `null`；如果键已存在，则会更新值并返回旧值。`add` 方法正是利用 `put` 方法的返回值是否为 `null` 来判断元素是否已存在，从而保证了集合中元素的唯一性。</div>
          </div>
          <div class="card-source">来源: 3. TreeSet 的实现原理 - TreeSet 的实现</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">TreeMap 和 TreeSet 是如何保证其内部元素是有序的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">它们通过底层的红黑树（一种二叉查找树）来保证有序性。在插入元素时，会根据元素的自然顺序或通过构造时传入的 `Comparator` 来比较元素大小，并将其放置在树中的正确位置，从而在遍历时能够得到有序的结果。</div>
          </div>
          <div class="card-source">来源: 2. TreeMap 的实现原理 - TreeMap 基本结构</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
